package org.example.erpapiservicespringmongoimpl;

import org.example.erpapicommon.Util.BasePage;
import org.example.erpapicommon.Util.Pageable;
import org.example.erpapicommon.Util.Param.OrderQueryParam;
import org.example.erpapicommon.model.Order;
import org.example.erpapicommon.model.TOrder;
import org.example.erpapicommon.model.TOrderDetail;
import org.example.erpapicommon.model.TProduct;
import org.example.erpapicommon.service.OrderService;
import org.example.erpapiservicespringmongoimpl.doc.OrderDoc;
import org.example.erpapiservicespringmongoimpl.doc.ProductDoc;
import org.example.erpapiservicespringmongoimpl.mapper.OrderMapper;
import org.example.erpapiservicespringmongoimpl.mapper.OrderPageMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Component
public class OrderServiceMongoImpl implements OrderService {
    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    OrderPageMapper orderPageMapper;
    @Override
    @Cacheable(value = "erp_api",key = "'pageOrders_'+#param.toString()", condition = "#param != null")
    public Pageable<TOrder> getOrders(OrderQueryParam param) {
        List<Criteria> criteriaList =new ArrayList<>();
        String customerName = param.getCustomerName();
        if (customerName!=null&&!customerName.isBlank()){
            criteriaList.add(Criteria.where("customerName").regex(customerName));
        }
        Date startDate = param.getStartDate();
        if (startDate!=null){
            criteriaList.add(Criteria.where("orderDate").gte(startDate));
        }
        Date endDate = param.getEndDate();
        if (endDate!=null){
            criteriaList.add(Criteria.where("orderDate").lte(endDate));
        }
        String shipperName = param.getShipperName();
        if (shipperName!=null&&!shipperName.isBlank()){
            criteriaList.add(Criteria.where("shipperName").regex(shipperName));
        }
        String shipProvince = param.getShipProvince();
        if (shipProvince!=null&&!shipProvince.isBlank()){
            criteriaList.add(Criteria.where("shipProvince").regex(shipProvince));
        }
        String shipCity = param.getShipCity();
        if (shipCity!=null&&!shipCity.isBlank()){
            criteriaList.add(Criteria.where("shipCity").regex(shipCity));
        }
        String shipRegion = param.getShipRegion();
        if (shipRegion!=null&&!shipRegion.isBlank()){
            criteriaList.add(Criteria.where("shipRegion").regex(shipRegion));
        }
        String employeeName = param.getEmployeeName();
        if (employeeName!=null&&!employeeName.isBlank()){
            criteriaList.add(Criteria.where("employeeName").regex(employeeName));
        }
        Query query = new Query();
        Criteria criteria = new Criteria();
        if (!criteriaList.isEmpty()){
            criteria.andOperator(criteriaList);
        }
        query.addCriteria(criteria);
        long totalCount = mongoTemplate.count(query, OrderDoc.class);
        int pageSize = param.getPageSize();
        int pageNumber = param.getPageNumber();
        int totalPage = PageUtil.getTotalPage((int)totalCount, pageSize);
        int offset = PageUtil.getOffset(pageNumber, pageSize);
        query.skip(offset).limit(pageSize);
        List<OrderDoc> orderDocList = mongoTemplate.find(query, OrderDoc.class);
        List<TOrder> tOrderList = orderPageMapper.fromOrderDocToOrders(orderDocList);
        BasePage<TOrder> tOrderPageable = new BasePage<>(tOrderList, pageNumber, pageSize, totalPage, (int)totalCount);
        return tOrderPageable;
    }

    @Override
    @Cacheable(value = "erp_api",key = "'findOrderisByid_'+#id")
    public Optional<Order> getOrdersById(String id) {
        Query query = Query.query(Criteria.where("id").is(id));
        OrderDoc orderDoc = mongoTemplate.findById(id, OrderDoc.class);
        if (orderDoc==null){
            return Optional.empty();
        }
        Order order = orderMapper.fromOrderDocToOrder(orderDoc);
        return Optional.of(order);
    }

}
